﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Windows.Media.Imaging;
using System.Resources;
using System.Configuration;
using System.Globalization;
using System.Threading;
using System.Windows.Data;
using System.Collections;
using Gaiocorp.SLMapViewer.Legend;
using Liquid;
using SilverlightDragNDrop;

namespace Gaiocorp.SLMapViewer
{
    public partial class MapControl : UserControl
    {
        public Int32 X = 0, Y = 0;
        bool dragInProgress = false;
        bool blMouseDown = false;
        int iClicks = 0;
        //Point dragOffset;
        Point pntUserClick;
        //Rectangle blueRectangle = new Rectangle();
        String xmlString = string.Empty;
        private IDictionary<string, string> _parameters = null;
        private LegendLayers allLyrs = new LegendLayers();
        private List<Point> _points = new List<Point>();
        private Line _aSegment = new Line();
        private List<Line> _Segments = new List<Line>();
        private int iMeasureClicks = 0;

        private System.Windows.Shapes.Path _MeasureLine = new System.Windows.Shapes.Path();
        //private LineGeometry


        public MapControl(IDictionary<string, string> parameters)
        {
            this._parameters = parameters;
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Page_Loaded);
            Application.Current.Host.Content.Resized += new EventHandler(Content_Resized);
            //this.OnMouseWheel
            //InitializeMouseWheel();
            InitializeRightMouseButton();
            InitializeControlLocations();
            gridLegend.Tag = null;

            DragManager dm = new DragManager(LayoutRoot);
            //dm.EnableDragableElement(MapImg);
            dm.EnableDragableElement(brdResults);
            dm.EnableDragableElement(brdQuery);
            dm.EnableDragableElement(brdPrint);
            dm.EnableDragableElement(brdError);

            string c = System.Threading.Thread.CurrentThread.CurrentCulture.Name.ToString();

            // Get the culture of the currently executing thread.
            // The value of ci will determine the culture of
            // the resources that the resource manager retrieves.
            CultureInfo ci = Thread.CurrentThread.CurrentUICulture;
            Gaiocorp.SLMapViewer.Resources.SLMapViewer.Culture = ci;
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            //MapImg.Width=Session["MAPWIDTH"]

            string s = System.Windows.Browser.HtmlPage.Document.DocumentUri.AbsoluteUri;
            HtmlPage.RegisterScriptableObject("SilverlightMapObject", this);
            HtmlElement txtRequest = HtmlPage.Document.GetElementById(_parameters["RequestControlID"].ToString());
            if (txtRequest.GetProperty("value").ToString() == string.Empty)
            {
                stxtRequest.Text = "<REQUEST action='InitMap' reset='yes' sessionid='" + _parameters["SessionID"] + "' />";
            }
            else
            {
                stxtRequest.Text = "<REQUEST " + txtRequest.GetProperty("value").ToString() + " reset='yes' sessionid='" + _parameters["SessionID"] + "' />";
            }
        }

        void Content_Resized(object sender, EventArgs e)
        {
            //Sv.Width = gridLegCont.ColumnDefinitions[Grid.GetColumn(Sv as FrameworkElement)].ActualWidth;
            // Sv.Height = gridLegCont.RowDefinitions[Grid.GetRow(Sv as FrameworkElement)].ActualHeight;
        }

        private void InitializeControlLocations()
        {
            this.cnvMap.Width = Convert.ToDouble(_parameters["Width"].ToString());
            this.cnvMap.Height = Convert.ToDouble(_parameters["Height"].ToString());
            this.MapImg.Width = Convert.ToDouble(_parameters["Width"].ToString());
            this.MapImg.Height = Convert.ToDouble(_parameters["Height"].ToString());
            rectMap.Width = MapImg.Width;
            rectMap.Height = MapImg.Height;
            RowDefinition treeRow = gridLegCont.RowDefinitions[2];
            RowDefinition LegTitleRow = gridLegCont.RowDefinitions[0];

            if (_parameters["InternalControls"].ToString() == "1")
            {
                DragManager dm = new DragManager(LayoutRoot);
                dm.EnableDragableElement(brdLegend);
                this.LayoutRoot.Width = Convert.ToDouble(_parameters["Width"].ToString());
                this.LayoutRoot.Height = Convert.ToDouble(_parameters["Height"].ToString());
                //brdMain.Width = MapImg.Width+4;
                cnvLegend.Visibility = Visibility.Collapsed;
                cnvLegend.SetValue(Canvas.TopProperty, Convert.ToDouble(50));
                cnvLegend.SetValue(Canvas.LeftProperty, Convert.ToDouble(50));
                cnvLegend.MaxWidth = MapImg.Width - 50;
                cnvLegend.MaxHeight = MapImg.Height - 50;
                xbtnCloseLegend.SetValue(Grid.ColumnProperty, 0);
                xbtnCloseLegend.SetValue(Grid.ColumnSpanProperty, 3);
                xbtnCloseLegend.HorizontalAlignment = HorizontalAlignment.Center;
                //xbtnCloseLegend.SetValue(Grid.RowProperty, 1);
                treeRow.Height = new GridLength(cnvLegend.MaxHeight - 70);
                this.treeLegend.Height = treeRow.Height.Value;
            }
            else
            {

                this.Width = Convert.ToDouble(MapImg.Width + treeLegend.Width);
                this.Height = Convert.ToDouble(_parameters["Height"].ToString());
                this.LayoutRoot.Width = Convert.ToDouble(MapImg.Width + treeLegend.Width);
                this.LayoutRoot.Height = Convert.ToDouble(_parameters["Height"].ToString());
                brdLegend.CornerRadius = new CornerRadius(Convert.ToDouble(0));
                cnvLegend.SetValue(Canvas.TopProperty, Convert.ToDouble(0));
                cnvLegend.SetValue(Canvas.LeftProperty, MapImg.Width);
                cnvLegend.Visibility = Visibility.Visible;
                //cnvLegend.Width = LayoutRoot.Width - MapImg.Width;
                cnvLegend.Height = MapImg.Height;
                brdLegend.Height = MapImg.Height;
                brdLegend.Width = treeLegend.Width + 1;

                gridLegend.SetValue(Grid.RowProperty, 1);
                gridLegend.SetValue(Grid.RowSpanProperty, 2);
                treeRow.Height = new GridLength(cnvLegend.Height - LegTitleRow.Height.Value);
                this.treeLegend.Height = treeRow.Height.Value;
                xbtnCloseLegend.Visibility = Visibility.Collapsed;
                //gridLegCont.Width = cnvLegend.Width;
                //gridLegCont.Height = cnvLegend.Height;
                //gridLegend.Width = cnvLegend.Width;
                //gridLegend.Height = cnvLegend.Height;

                //cnvLegend.SetValue(Canvas.TopProperty, Convert.ToDouble(0));
                //cnvLegend.SetValue(Canvas.LeftProperty, MapImg.Width - 15);

            }
            if (_parameters["DebugOn"].ToString() == "1")
                gridDebug.Visibility = Visibility.Visible;
            else gridDebug.Visibility = Visibility.Collapsed;

            //Set the status bar
            brdStatus.SetValue(Canvas.TopProperty, (MapImg.Height - brdStatus.Height));
            brdStatus.SetValue(Canvas.LeftProperty, (double)0);
            brdStatus.Width = MapImg.Width;
            // Center wait window
            brdWait.SetValue(Canvas.TopProperty, this.MapImg.Height / 2 - brdWait.Height / 2);
            brdWait.SetValue(Canvas.LeftProperty, this.MapImg.Width / 2 - brdWait.Width / 2);
            //Center error window
            brdError.SetValue(Canvas.TopProperty, this.MapImg.Height / 2 - brdError.Height / 2);
            brdError.SetValue(Canvas.LeftProperty, this.MapImg.Width / 2 - brdError.Width / 2);
            //Resize results window
            gridDataResults.Width = (this.MapImg.Width - 50);
            gridDataResults.Height = (this.MapImg.Height / 4);
            //Resize query window
            brdQuery.MaxHeight = (this.MapImg.Height - 50);
            brdQuery.MaxWidth = (this.MapImg.Width - 50);
            gridQuery.MaxHeight = brdQuery.MaxHeight;
            gridQuery.MaxWidth = brdQuery.MaxWidth;

            //brdQuery.MaxWidth = gridQuery.Width+10; 
        }

        # region Load Map and Async response/requests
        [ScriptableMember]
        public void LoadMap()
        {
            brdWait.Visibility = Visibility.Visible;
            String serviceUrl = _parameters["MapServiceUrl"].ToString();

            //Uri serviceUri1 = new Uri(App.Current.Host.Source, "../MapServer/xml.aspx");
            //string serviceUrl1 = serviceUri1.AbsoluteUri;
            Uri serviceUri = new Uri(serviceUrl);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceUri);
            request.Method = "POST";
            request.ContentType = "text/xml";
            //request.
            AsyncCallback asyncCallback = new AsyncCallback(RequestProceed);
            try
            {
                IAsyncResult a = request.BeginGetRequestStream(asyncCallback, request); // dies here
            }
            catch (Exception e1)
            {
                //Log.Text = e1.StackTrace;
            }
        }

        void RequestProceed(IAsyncResult asyncResult)
        {

            this.Dispatcher.BeginInvoke(delegate() //If you dont put this line you get access errors.
            {
                HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
                StreamWriter postDataWriter = new StreamWriter(request.EndGetRequestStream(asyncResult));

                String requestXML = this.stxtRequest.Text;
                //Make sure its a valid xml
                if (requestXML != string.Empty && requestXML.Trim().StartsWith("<") && requestXML.Trim().EndsWith(">"))
                {
                    postDataWriter.Write(requestXML);
                    postDataWriter.Close();
                    request.BeginGetResponse(new AsyncCallback(ResponseProceed), request);
                }
            });
        }

        void ResponseProceed(IAsyncResult asyncResult)
        {
            this.Dispatcher.BeginInvoke(delegate() //If you dont put this line you get access errors.
            {
                try
                {
                    HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;

                    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
                    StreamReader responseReader = new StreamReader(response.GetResponseStream());
                    String responseString = responseReader.ReadLine();
                    stxtResponse.Text = responseString;
                    XDocument doc = XDocument.Parse(responseString);
                    XElement xEl1 = doc.Element("RESPONSE");
                    //Check if we got returned any errors
                    XElement xElError = xEl1.Element("ERROR");
                    if (xElError != null)
                    {
                        //Display Error window
                        brdError.Visibility = Visibility.Visible;
                        txbErrBody.Text = xElError.FirstNode.ToString();
                    }
                    else
                    {
                        XElement xEl2 = xEl1.Element("IMAGE");
                        if (xEl2 != null)
                        {
                            this.cnvMap.Width = (double)xEl2.Attribute("width");
                            this.cnvMap.Width = (double)xEl2.Attribute("height");
                            string strIMageURL = (string)xEl2.Attribute("imageURL");
                            stxtXMin.Text = (string)xEl2.Attribute("minx");
                            stxtXMax.Text = (string)xEl2.Attribute("maxx");
                            stxtYMin.Text = (string)xEl2.Attribute("miny");
                            stxtYMax.Text = (string)xEl2.Attribute("maxy");
                            txtScale.Text = (string)xEl2.Attribute("scale");
                            //Populate selection flag
                            try
                            {
                                stxtHasSelection.Text = (string)xEl2.Attribute("selectionmap");
                            }
                            catch
                            {
                                stxtHasSelection.Text = "no";
                            }
                            Image img = new Image();
                            Uri uri = new Uri(strIMageURL.ToString(), UriKind.Absolute);
                            ImageSource imgSource = new BitmapImage(uri);
                            this.MapImg.Source = imgSource;
                            Canvas.SetLeft(cnvMap, 0);
                            Canvas.SetTop(cnvMap, 0);
                            Canvas.SetLeft(MapImg, 0);
                            Canvas.SetTop(MapImg, 0);
                            myStoryboard.Begin();

                            //Now get the extent and populate the hidden fields
                            // This is so we have the geographic extent of the map
                            // so we can use it for when hovering the mouse over the map image 
                            //XElement xEl3 = xEl1.Element("FULLEXTENT");
                            //stxtXMin.Text = (string)xEl3.Attribute("minx");
                            //stxtXMax.Text = (string)xEl3.Attribute("maxx");
                            //stxtYMin.Text = (string)xEl3.Attribute("miny");
                            //stxtYMax.Text = (string)xEl3.Attribute("maxy");
                            XElement xElm = doc.Element("LEGEND");
                            PopulateLegend(responseString);
                        }

                        //Populate the identify/table grid control
                        CreateIdentifyGrid(responseString);

                        //Populate the layer drop down in the Query dialog
                        BindCboToLayers();

                        //Check if we got return an external URL
                        XElement xElURL = xEl1.Element("EXTERNALURL");
                        if (xElURL != null)
                        {
                            GoToUrl(xElURL.Value);
                        }
                        //Check if we got return an external URL
                        XElement xElPrint = xEl1.Element("PRINTIMAGE");
                        if (xElPrint != null)
                        {
                            ComboBoxItem cbi = (ComboBoxItem)cboPaperSizes.SelectedItem;
                            Uri serviceUri = new Uri(App.Current.Host.Source, "../MapServer/PrintTemplates/GenPrintTemplate.aspx?pso=" + cbi.Tag.ToString() + "&title=" + txtPrintTitle.Text);

                            GoToUrl(serviceUri.ToString());
                        }
                    }
                }
                catch (Exception Ex)
                {
                    brdError.Visibility = Visibility.Visible;
                    txbErrBody.Text = Ex.Message.ToString();
                }
                finally
                {
                    //Hide the 'please wait' window
                    brdWait.Visibility = Visibility.Collapsed;
                }
            }
            );


        }
        # endregion

        # region Mouse and Keyboard Events on Map Image
        private void MapImg_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.GetPosition(MapImg).Y > 24)
            {
                dragInProgress = true;
                //blMouseDown = true;
                MapImg.CaptureMouse();
                //if (stxtActiveTool.Text != "MEASURE")
                //{
                //if (iClicks == 0)
                //{
                pntUserClick = e.GetPosition(LayoutRoot);
                //    iClicks++;
                //}
                //}
                //else 
                //{
                ////---add the line to the canvas---
                //if (cnvMap.Children.Contains(_MeasureLine) == false)
                //{
                //    pntUserClick = e.GetPosition(MapImg);
                //    cnvMap.Children.Add(_MeasureLine);
                //}
                //else
                //{
                //    PathGeometry pathGeometry = (PathGeometry)_MeasureLine.Data;
                //    PathFigure aFigure = pathGeometry.Figures.ElementAt(pathGeometry.Figures.Count - 1);
                //    PolyLineSegment aPolyLSeg = (PolyLineSegment)aFigure.Segments.ElementAt(aFigure.Segments.Count-1);
                //    //aPolyLSeg.
                //    //LineSegment aSegment = (LineSegment)aPolyLSeg.El(aPolyLSeg.Count() - 1);
                //    Point aPoint = aPolyLSeg.Points.ElementAt(aPolyLSeg.Points.Count-1);
                //    pntUserClick = aPoint;
                //}
                //---save the current point for later use---
                //_previousPoint = e.GetPosition(MapImg);

                //---add the point where the user clicked---
                //_points.Add(pntUserClick);
                //-- add the segments to the line collection
                //if (_points.Count > 1) _Segments.Add(_aSegment);

                //}
                if (stxtActiveTool.Text == "MEASURE")
                {
                    UserMeasureLine.Visibility = Visibility.Visible;
                    gridMeasureToolTip.Visibility = Visibility.Visible;
                    //if (iMeasureClicks > 1)
                    //{
                    //Canvas.SetLeft(UserMeasureLine, pntUserClick.X);
                    UserMeasureLine.X1 = pntUserClick.X;
                    UserMeasureLine.Y1 = pntUserClick.Y;
                    //UserMeasureLine.X2 = currentMousePosition.X;
                    //UserMeasureLine.Y2 = currentMousePosition.Y;
                    //}
                    iMeasureClicks++;
                }
            }
        }

        private void MapImg_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (this.dragInProgress && e.GetPosition(MapImg).Y > 24)
            {
                iClicks = 0;
                this.dragInProgress = false;
                ClearDynamicShapes();

                switch (stxtActiveTool.Text)
                {
                    case "ZOOMIN":
                        this.stxtRequest.Text = "<REQUEST ymax='" + e.GetPosition(MapImg).Y.ToString() + "' xmax='" + e.GetPosition(MapImg).X.ToString() + "' ymin='" + pntUserClick.Y.ToString() + "' xmin='" + pntUserClick.X.ToString() + "' action='ZoomInBox' sessionid='" + _parameters["SessionID"] + "' />";
                        break;
                    case "ZOOMOUT":
                        this.stxtRequest.Text = "<REQUEST ymax='" + e.GetPosition(MapImg).Y.ToString() + "' xmax='" + e.GetPosition(MapImg).X.ToString() + "' ymin='" + pntUserClick.Y.ToString() + "' xmin='" + pntUserClick.X.ToString() + "' action='ZoomOutBox' sessionid='" + _parameters["SessionID"] + "' />";
                        break;
                    case "PAN":
                        this.stxtRequest.Text = "<REQUEST ymax='" + e.GetPosition(MapImg).Y.ToString() + "' xmax='" + e.GetPosition(MapImg).X.ToString() + "' ymin='" + pntUserClick.Y.ToString() + "' xmin='" + pntUserClick.X.ToString() + "' action='Pan' sessionid='" + _parameters["SessionID"] + "' />";
                        //this.stxtRequest.Text = "<REQUEST ymax='" + currentMousePosition.Y.ToString() + "' xmax='" + e.GetPosition(MapImg).X.ToString() + "' ymin='" + pntUserClick.Y.ToString() + "' xmin='" + pntUserClick.X.ToString() + "' action='Pan' />";
                        break;
                    case "ADDPIN":
                        this.stxtRequest.Text = "<REQUEST ymax='" + e.GetPosition(MapImg).Y.ToString() + "' xmax='" + e.GetPosition(MapImg).X.ToString() + "' ymin='" + pntUserClick.Y.ToString() + "' xmin='" + pntUserClick.X.ToString() + "' action='GetXYButton' sessionid='" + _parameters["SessionID"] + "' />";
                        break;
                    case "SELECT":
                        this.stxtRequest.Text = "<REQUEST ymax='" + e.GetPosition(MapImg).Y.ToString() + "' xmax='" + e.GetPosition(MapImg).X.ToString() + "' ymin='" + pntUserClick.Y.ToString() + "' xmin='" + pntUserClick.X.ToString() + "' action='SELECT' sessionid='" + _parameters["SessionID"] + "' />";
                        break;
                    case "INFO":
                        this.stxtRequest.Text = "<REQUEST ymax='" + e.GetPosition(MapImg).Y.ToString() + "' xmax='" + e.GetPosition(MapImg).X.ToString() + "' ymin='" + pntUserClick.Y.ToString() + "' xmin='" + pntUserClick.X.ToString() + "' action='INFO' sessionid='" + _parameters["SessionID"] + "' />";
                        brdResults.Visibility = Visibility.Visible;
                        brdResults.SetValue(Canvas.TopProperty, Convert.ToDouble(50));
                        //gridResults.SetValue(Canvas.TopProperty, Convert.ToDouble(50));
                        break;
                    case "HYPERLINK":
                        DoUrlRequest(pntUserClick.X, e.GetPosition(MapImg).X, pntUserClick.Y, e.GetPosition(MapImg).Y);
                        break;
                    case "MEASURE":
                        //UserMeasureLine.Visibility = Visibility.Collapsed;
                        break;
                    case "ADDPNT":
                        this.stxtRequest.Text = "<REQUEST ymax='" + e.GetPosition(MapImg).Y.ToString() + "' xmax='" + e.GetPosition(MapImg).X.ToString() + "' ymin='" + pntUserClick.Y.ToString() + "' xmin='" + pntUserClick.X.ToString() + "' action='ADDSHPPNT' sessionid='" + _parameters["SessionID"] + "' />";
                        brdResults.Visibility = Visibility.Visible;
                        brdResults.SetValue(Canvas.TopProperty, Convert.ToDouble(50));
                        gridDataResults.IsReadOnly = false;
                        break;
                }
                MapImg.ReleaseMouseCapture();
            }
        }

        private void DoUrlRequest(double xmin, double xmax, double ymin, double ymax)
        {
            LegendLayer aLyr = allLyrs.getActiveLayer();
            this.stxtRequest.Text = "<REQUEST ymax='" + ymax.ToString() + "' xmax='" + xmax.ToString() + "' ymin='" + ymin.ToString() + "' xmin='" + xmin.ToString() + "' action='HYPERLINK' layer='" + aLyr.Name + "' linkfield='" + aLyr.HLinkField + "' linkParams='" + aLyr.HLinkParams + "' sessionid='" + _parameters["SessionID"] + "' />";
        }

        private void MapImg_MouseMove(object sender, MouseEventArgs e)
        {
            Point currentMousePosition = e.GetPosition(this.MapImg);

            if (stxtActiveTool.Text == "ZOOMIN" || stxtActiveTool.Text == "ZOOMOUT" || stxtActiveTool.Text == "SELECT")
            {
                if (dragInProgress && e.GetPosition(MapImg).Y > 24)
                {
                    double dblWidth = Math.Abs(currentMousePosition.X - pntUserClick.X);
                    double dblHeight = Math.Abs(currentMousePosition.Y - pntUserClick.Y);
                    if (pntUserClick.X < currentMousePosition.X && pntUserClick.Y < currentMousePosition.Y)
                    {
                        Canvas.SetLeft(dynrectangle, pntUserClick.X);
                        Canvas.SetTop(dynrectangle, pntUserClick.Y);

                        dynrectangle.Height = dblHeight;
                        dynrectangle.Width = dblWidth;
                    }

                }
            }
            else if (stxtActiveTool.Text == "PAN")
            {
                if (dragInProgress && e.GetPosition(MapImg).Y > 24)
                {
                    MapImg.CaptureMouse();
                    Canvas.SetLeft(this.MapImg, currentMousePosition.X - pntUserClick.X);
                    Canvas.SetTop(this.MapImg, currentMousePosition.Y - pntUserClick.Y);
                    List<UIElement> collidedElements = VisualTreeHelper.FindElementsInHostCoordinates(currentMousePosition, this.LayoutRoot) as List<UIElement>;
                    collidedElements.Remove(MapImg);
                    collidedElements.Remove(this.LayoutRoot);

                    //if (collidedElements.Count() > 0)
                    //{
                    //    CollisionEventArgs args = new CollisionEventArgs() { Element = MapImg, Position = currentMousePosition, CollidedElements = collidedElements };
                    //    Collision(this, args);
                    //}
                    //Point currentMousePosition = e.GetPosition(layoutRoot);
                    //TranslateTransform transform = GetTranslateTransform(MapImg);
                    //TranslateTransform transform = new TranslateTransform();
                    //MapImg.RenderTransform = transform;
                    //double mouseX = currentMousePosition.X - pntUserClick.X;
                    //double mouseY = currentMousePosition.Y - pntUserClick.Y;
                    //transform.X += mouseX;
                    //transform.Y += mouseY;
                    //if (Collision != null)
                    //{
                    //    List<UIElement> collidedElements = VisualTreeHelper.FindElementsInHostCoordinates(currentMousePosition, layoutRoot) as List<UIElement>;
                    //    collidedElements.Remove(element);
                    //    collidedElements.Remove(layoutRoot);

                    //    if (collidedElements.Count() > 0)
                    //    {
                    //        CollisionEventArgs args = new CollisionEventArgs() { Element = element, Position = currentMousePosition, CollidedElements = collidedElements };
                    //        Collision(this, args);
                    //    }
                    //}
                }
            }
            else if (stxtActiveTool.Text == "MEASURE")
            {
                if (dragInProgress && e.GetPosition(MapImg).Y > 24)
                {
                    //Canvas.SetLeft(UserMeasureLine, pntUserClick.X);
                    //Canvas.SetTop(UserMeasureLine, pntUserClick.Y);
                    UserMeasureLine.X1 = pntUserClick.X;
                    UserMeasureLine.Y1 = pntUserClick.Y;
                    UserMeasureLine.X2 = currentMousePosition.X;
                    UserMeasureLine.Y2 = currentMousePosition.Y;
                    Canvas.SetLeft(gridMeasureToolTip, currentMousePosition.X - 10);
                    Canvas.SetTop(gridMeasureToolTip, currentMousePosition.Y - 20);
                    gridMeasureToolTip.Visibility = Visibility.Visible;
                    txbMeasLength.Text = string.Format("{0:0.00}", ReturnGeoLength(pntUserClick.X, pntUserClick.Y, currentMousePosition.X, currentMousePosition.Y).ToString());
                    //---add the current point---
                    //Point currentPoint = e.GetPosition(MapImg);
                    //_points.Add(currentMousePosition);

                    //List<UIElement> collidedElements = VisualTreeHelper.FindElementsInHostCoordinates(currentMousePosition, MapImg) as List<UIElement>;

                    //foreach (UIElement el in collidedElements)
                    //{
                    //    string strElName = el.GetValue(FrameworkElement.NameProperty).ToString();
                    //}


                    //---draws a line connecting the previous
                    // point and the current point---

                    // _aSegment.X1 = pntUserClick.X;
                    // _aSegment.Y1 = pntUserClick.Y;
                    // _aSegment.X2 = currentMousePosition.X;
                    // _aSegment.Y2 = currentMousePosition.Y;
                    // _aSegment.StrokeThickness = 2;
                    // _aSegment.Stroke = new SolidColorBrush(Colors.Black);
                    // _Segments.Add(_aSegment);
                    // PolyLineSegment _PolyLSeg = new PolyLineSegment();
                    // int sc = _Segments.Count;
                    //foreach (Line aLine in _Segments)
                    // {

                    //    Point aPnt1= new Point(aLine.X1, aLine.Y1);
                    //    Point aPnt2 = new Point(aLine.X2, aLine.Y2);
                    //    _PolyLSeg.Points.Add(aPnt1);
                    //    _PolyLSeg.Points.Add(aPnt2);
                    //     //_MeasureLine
                    // }
                    // PathFigure pathFigure = new PathFigure();
                    // pathFigure.StartPoint = _points.ElementAt(0);
                    // //pathFigure.StartPoint = pntUserClick;
                    // //pathFigure.Segments.Clear();
                    // pathFigure.Segments.Add(_PolyLSeg);
                    // PathGeometry pathGeometry = new PathGeometry();
                    // pathGeometry.Figures.Add(pathFigure);
                    // _MeasureLine.StrokeThickness = 2;
                    // _MeasureLine.Stroke = new SolidColorBrush(Colors.Black);
                    // _MeasureLine.Data = pathGeometry;

                }
            }
            Point pntRealPnt = pixel2point(e.GetPosition(MapImg).X, e.GetPosition(MapImg).Y);
            stxtStatusBar.Text = Gaiocorp.SLMapViewer.Resources.SLMapViewer.X.ToString() + string.Format("{0:0.00}", pntRealPnt.X) + "  " + Gaiocorp.SLMapViewer.Resources.SLMapViewer.Y.ToString() + String.Format("{0:0.00}", pntRealPnt.Y);
            //stxtStatusBar.Text = "Current XY:" + e.GetPosition(MapImg).X.ToString() + " : " + e.GetPosition(MapImg).Y.ToString();
        }

        private TranslateTransform GetTranslateTransform(UIElement element)
        {
            TranslateTransform translateTransform = null;
            if (element.RenderTransform is TranslateTransform)
            {
                translateTransform = element.RenderTransform as TranslateTransform;
            }
            else if (element.RenderTransform is TransformGroup)
            {
                TransformGroup group = element.RenderTransform as TransformGroup;
                foreach (GeneralTransform transform in group.Children)
                {
                    if (transform is TranslateTransform)
                    {
                        translateTransform = transform as TranslateTransform;
                    }
                }
            }
            else
            {
                translateTransform = new TranslateTransform();
                element.RenderTransform = translateTransform;
            }
            return translateTransform;
        }

        private void MapImg_MouseLeave(object sender, MouseEventArgs e)
        {
            if (this.dragInProgress)
            {
                this.dragInProgress = false;
                ClearDynamicShapes();
            }
        }

        protected void MapImg_LostMouseCapture(object sender, MouseEventArgs e)
        {
            if (this.dragInProgress)
            {
                this.dragInProgress = false;
                ClearDynamicShapes();

            }
        }

        private void ClearDynamicShapes()
        {
            dynrectangle.Height = 0;
            dynrectangle.Width = 0;
            Canvas.SetLeft(dynrectangle, -99);
            Canvas.SetTop(dynrectangle, -99);
            UserMeasureLine.X1 = 0;
            UserMeasureLine.Y1 = 0;
            UserMeasureLine.X2 = 0;
            UserMeasureLine.Y2 = 0;
            gridMeasureToolTip.Visibility = Visibility.Collapsed;
        }

        private void txtScale_KeyDown(object sender, KeyEventArgs e)
        {
            //Set map scale
            if (e.Key == Key.Enter)
            {
                stxtRequest.Text = "<REQUEST action='SetScale' scale='" + txtScale.Text + "' sessionid='" + _parameters["SessionID"] + "' />";
            }
        }
        # endregion

        # region XAML Control Events
        protected void OnMouseWheel(object sender, HtmlEventArgs e)
        {
            if (MapImg.IsHitTestVisible == false) return;
            double mouseDelta = 0;
            ScriptObject eventObject = e.EventObject;

            // Mozilla and Safari
            if (eventObject.GetProperty("detail") != null)
                mouseDelta = ((double)eventObject.GetProperty("detail"));

            // IE and Opera
            else if (eventObject.GetProperty("wheelDelta") != null)
                mouseDelta = ((double)eventObject.GetProperty("wheelDelta"));

            mouseDelta = Math.Sign(mouseDelta);

            if (mouseDelta > 0)
            {
                if (stxtRequest.Text == "<REQUEST action='ZoomIn' sessionid='" + _parameters["SessionID"] + "' />")
                {
                    stxtRequest_TextChanged(stxtRequest, null);
                }
                else
                    stxtRequest.Text = "<REQUEST action='ZoomIn' sessionid='" + _parameters["SessionID"] + "' />";
            }


            if (mouseDelta < 0)
            {
                if (stxtRequest.Text == "<REQUEST action='ZoomOut' sessionid='" + _parameters["SessionID"] + "' />")
                {
                    stxtRequest_TextChanged(stxtRequest, null);
                }
                else
                    stxtRequest.Text = "<REQUEST action='ZoomOut' sessionid='" + _parameters["SessionID"] + "' />";
            }


            if (mouseDelta != 0)
            {
                e.PreventDefault();
                eventObject.SetProperty("returnValue", false);
            }
        }

        protected void OnContextMenu(object sender, HtmlEventArgs e)
        {
            ScriptObject eventObject = e.EventObject;

            //if (rectanglePaintBrush.Color == Colors.Blue)
            //    rectanglePaintBrush.Color = Colors.Green;
            //else
            //    rectanglePaintBrush.Color = Colors.Blue;

            e.PreventDefault();
            e.StopPropagation();
            eventObject.SetProperty("returnValue", false);
        }

        private void InitializeMouseWheel()
        {
            HtmlPage.Window.AttachEvent("DOMMouseScroll", this.OnMouseWheel); // Mozilla
            HtmlPage.Window.AttachEvent("onmousewheel", this.OnMouseWheel);
            HtmlPage.Document.AttachEvent("onmousewheel", this.OnMouseWheel); // IE
        }

        private void InitializeRightMouseButton()
        {
            //HtmlPage.Document.GetElementById("Silverlight1").AttachEvent("oncontextmenu", this.OnContextMenu);
        }
        # endregion


        # region Utilities

        private Point pixel2point(double pixelX, double pixelY)
        {
            if (stxtXMax.Text == string.Empty || stxtXMin.Text == string.Empty)
            {
                Point pointNull = new Point(0, 0);
                return pointNull;
            }

            // Make sure we use the right number format

            //Get the current culture
            CultureInfo ci = Thread.CurrentThread.CurrentUICulture;
            //Get number format for culture
            string numSep = ci.NumberFormat.NumberDecimalSeparator;
            //Replace any occurences of . or , with the correct number separator
            stxtXMax.Text = stxtXMax.Text.Replace(",", numSep);
            stxtXMax.Text = stxtXMax.Text.Replace(".", numSep);
            stxtXMin.Text = stxtXMin.Text.Replace(",", numSep);
            stxtXMin.Text = stxtXMin.Text.Replace(".", numSep);
            stxtYMax.Text = stxtYMax.Text.Replace(",", numSep);
            stxtYMax.Text = stxtYMax.Text.Replace(".", numSep);
            stxtYMin.Text = stxtYMin.Text.Replace(",", numSep);
            stxtYMin.Text = stxtYMin.Text.Replace(".", numSep);
            double RealmapWidth = Convert.ToDouble(stxtXMax.Text) - Convert.ToDouble(stxtXMin.Text);
            double RealmapHeight = Convert.ToDouble(stxtYMax.Text) - Convert.ToDouble(stxtYMin.Text);

            double mapWidth = MapImg.Width;
            double mapHeight = MapImg.Height;
            double xperc;
            double yperc;
            xperc = pixelX / mapWidth;
            yperc = (mapHeight - pixelY) / mapHeight;
            double Realx = Convert.ToDouble(stxtXMin.Text) + xperc * RealmapWidth;
            double Realy = Convert.ToDouble(stxtYMin.Text) + yperc * RealmapHeight;
            Point pointMap = new Point(Realx, Realy);
            return pointMap;
        }
        private double ReturnGeoLength(double pixelX1, double pixelY1, double pixelX2, double pixelY2)
        {
            double realLength;
            double geoX1, geoY1, geoX2, geoY2;
            double Dx, Dy;
            Point pntFrom = pixel2point(pixelX1, pixelY1);
            Point pntTo = pixel2point(pixelX2, pixelY2);
            geoX1 = pntFrom.X;
            geoY1 = pntFrom.Y;
            geoX2 = pntTo.X;
            geoY2 = pntTo.Y;
            Dx = geoX2 - geoX1;
            Dy = geoY2 - geoY1;
            realLength = Math.Sqrt((Dx * Dx) + (Dy * Dy));
            //realLength = Math.Sqrt(((geoY2 - geoY1) * (geoY2 - geoY1)) + ((geoX2 - geoX1) * (geoX2 - geoX1)));
            realLength = Convert.ToDouble(Math.Round(Convert.ToDecimal(realLength), 2));
            return realLength;

        }
        #endregion


        #region Map Toolbar
        private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Image currentTool = (Image)sender;
            string strName = currentTool.Name;
            Rectangle currentRect = (Rectangle)this.FindName(strName + "_rect");
            // Create a blue and a black Brush
            SolidColorBrush yellowBrush = new SolidColorBrush();
            yellowBrush.Color = Colors.Yellow;
            // Fill rectangle with blue color
            currentRect.Fill = yellowBrush;
            switch (strName)
            {
                case "FixZoomInImg":
                    if (stxtRequest.Text == "<REQUEST action='ZoomIn' sessionid='" + _parameters["SessionID"] + "' />")
                    {
                        stxtRequest_TextChanged(stxtRequest, null);
                    }
                    else
                        stxtRequest.Text = "<REQUEST action='ZoomIn' sessionid='" + _parameters["SessionID"] + "' />";

                    break;
                case "FixZoomOutImg":
                    if (stxtRequest.Text == "<REQUEST action='ZoomOut' sessionid='" + _parameters["SessionID"] + "' />")
                    {
                        stxtRequest_TextChanged(stxtRequest, null);
                    }
                    else
                        stxtRequest.Text = "<REQUEST action='ZoomOut' />";
                    break;
                case "PrevImg":
                    if (stxtRequest.Text == "<REQUEST action='ZoomLast' sessionid='" + _parameters["SessionID"] + "' />")
                    {
                        stxtRequest_TextChanged(stxtRequest, null);
                    }
                    else
                        stxtRequest.Text = "<REQUEST action='ZoomLast' sessionid='" + _parameters["SessionID"] + "' />";
                    break;
                case "InitImg":
                    if (stxtRequest.Text == "<REQUEST action='FullExtent' sessionid='" + _parameters["SessionID"] + "' />")
                    {
                        stxtRequest_TextChanged(stxtRequest, null);
                    }
                    else
                        stxtRequest.Text = "<REQUEST action='FullExtent' sessionid='" + _parameters["SessionID"] + "' />";
                    break;
                case "RemovePntImg":
                    if (stxtRequest.Text == "<REQUEST action='RemovePin' sessionid='" + _parameters["SessionID"] + "' />")
                    {
                        stxtRequest_TextChanged(stxtRequest, null);
                    }
                    else
                        stxtRequest.Text = "<REQUEST action='RemovePin' sessionid='" + _parameters["SessionID"] + "' />";
                    break;
                case "LegendImg":
                    if (gridLegend.Tag == null)
                    {
                        if (_parameters["SessionID"] != null)
                        {
                            stxtRequest.Text = "<REQUEST action='GetLegend' sessionid='" + _parameters["SessionID"] + "' />";
                        }
                        else
                        {
                            stxtRequest.Text = "<REQUEST action='GetLegend' sessionid='" + _parameters["SessionID"] + "' />";
                        }
                    }
                    if (_parameters["InternalControls"].ToString() == "1")
                    {
                        if (cnvLegend.Visibility == Visibility.Collapsed)
                        {
                            cnvLegend.SetValue(Canvas.TopProperty, Convert.ToDouble(30));
                            cnvLegend.SetValue(Canvas.LeftProperty, Convert.ToDouble(5));
                        }
                        cnvLegend.Visibility = Visibility.Visible;
                    }

                    break;
                case "QueryAttrsImg":
                    if (brdQuery.Visibility == Visibility.Collapsed)
                    {
                        brdQuery.SetValue(Canvas.TopProperty, Convert.ToDouble(30));
                        brdQuery.SetValue(Canvas.LeftProperty, Convert.ToDouble(5));
                    }
                    brdQuery.Visibility = Visibility.Visible;
                    break;
                case "TabImg":
                    if (brdResults.Visibility == Visibility.Collapsed)
                    {
                        brdResults.SetValue(Canvas.TopProperty, Convert.ToDouble(30));
                        brdResults.SetValue(Canvas.LeftProperty, Convert.ToDouble(5));
                    }
                    if (stxtHasSelection.Text == "no")
                    {
                        if (stxtActiveLayerName.Text != string.Empty)
                        {
                            stxtRequest.Text = "<REQUEST action='GetAttrTable' layer='" + stxtActiveLayerName.Text + "' sessionid='" + _parameters["SessionID"] + "' />";
                        }
                    }
                    brdResults.Visibility = Visibility.Visible;
                    break;
                case "PrintImg":
                    brdPrint.Visibility = Visibility.Visible;
                    break;
            }
        }
        private void Button_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Image currentTool = (Image)sender;
            string strName = currentTool.Name;
            Rectangle currentRect = (Rectangle)this.FindName(strName + "_rect");
            SolidColorBrush LightGreyBrush = new SolidColorBrush();
            LightGreyBrush.Color = Colors.LightGray;
            // Fill rectangle with blue color
            currentRect.Fill = LightGreyBrush;
            //ZoomInImg.Opacity = 0.3;
            //stxtRequest.Text = "<REQUEST action='ZoomOut' />";
            //LoadMap();
        }
        private void Tool_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Image currentTool = (Image)sender;
            string strName = currentTool.Name;
            Rectangle currentRect = (Rectangle)this.FindName(strName + "_rect");
            SolidColorBrush yellowBrush = new SolidColorBrush();
            yellowBrush.Color = Colors.Yellow;
            // Fill rectangle with blue color
            currentRect.Fill = yellowBrush;

            foreach (UIElement el in cnvToolbar.Children)
            {
                string strElName = el.GetValue(FrameworkElement.NameProperty).ToString();
                if (el.GetType() == typeof(Rectangle))
                {
                    Rectangle ar = (Rectangle)el;
                    if (ar.Name != currentRect.Name)
                    {
                        SolidColorBrush GreyBrush = new SolidColorBrush();
                        GreyBrush.Color = Colors.LightGray;
                        // Fill rectangle with blue color
                        ar.Fill = GreyBrush;
                    }

                }
            }
            switch (strName)
            {
                case "PanImg":
                    stxtActiveTool.Text = "PAN";
                    MapImg.Cursor = Cursors.Hand;
                    break;
                case "ZoomInImg":
                    stxtActiveTool.Text = "ZOOMIN";
                    MapImg.Cursor = Cursors.Arrow;
                    break;
                case "ZoomOutImg":
                    stxtActiveTool.Text = "ZOOMOUT";
                    MapImg.Cursor = Cursors.Arrow;
                    break;
                case "SelectImg":
                    stxtActiveTool.Text = "SELECT";
                    MapImg.Cursor = Cursors.Arrow;
                    break;
                case "InfoImg":
                    stxtActiveTool.Text = "INFO";
                    MapImg.Cursor = Cursors.Arrow;
                    break;
                case "AddPntImg":
                    stxtActiveTool.Text = "ADDPIN";
                    MapImg.Cursor = Cursors.Arrow;
                    break;
                case "HyperlImg":
                    stxtActiveTool.Text = "HYPERLINK";
                    MapImg.Cursor = Cursors.Arrow;
                    break;
                case "MeasureImg":
                    stxtActiveTool.Text = "MEASURE";
                    MapImg.Cursor = Cursors.Arrow;
                    break;
                case "CreatePntImg":
                    stxtActiveTool.Text = "ADDPNT";
                    MapImg.Cursor = Cursors.Arrow;
                    break;
            }
        }

        private void stxtRequest_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextBox txt = (TextBox)sender;
            if (txt.Text != string.Empty)
            {
                LoadMap();
            }

        }


        private void img1_ImageFailed(object sender, ExceptionRoutedEventArgs e)
        {
            Image img = sender as Image;
            // TODO: Display an image for error here
        }
        #endregion

        #region Legend

        // TODO : Replace with the Silveright 3 tree control

        private void PopulateLegend(string xmlResponse)
        {
            bool hasActiveLayer = false;
            allLyrs.Clear();
            if (xmlResponse == string.Empty)
            {
                SelectImg_rect.Visibility = Visibility.Collapsed;
                SelectImg.Visibility = Visibility.Collapsed;
                InfoImg_rect.Visibility = Visibility.Collapsed;
                InfoImg.Visibility = Visibility.Collapsed;
                return;
            }

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.XmlResolver = new XmlXapResolver();
            XmlReader reader = XmlReader.Create(new StringReader(xmlResponse));
            reader.MoveToContent();
            LegendLayer aLayer = new LegendLayer();
            int iLyrCount = 0;
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element && reader.Name == "LAYER")
                {
                    aLayer = new LegendLayer();
                    aLayer.Name = reader.GetAttribute("name").ToString();
                    aLayer.Title = reader.GetAttribute("title").ToString();
                    aLayer.Index = Convert.ToInt32(reader.GetAttribute("index").ToString());
                    aLayer.Visible = Convert.ToBoolean(Convert.ToInt32(reader.GetAttribute("isvisible").ToString()));
                    aLayer.Active = Convert.ToBoolean(Convert.ToInt32(reader.GetAttribute("isactive").ToString()));
                    aLayer.IsAnnotation = Convert.ToBoolean(Convert.ToInt32(reader.GetAttribute("annotation").ToString()));
                    aLayer.EnableActive = Convert.ToBoolean(Convert.ToInt32(reader.GetAttribute("canbeactive").ToString()));
                    aLayer.XLinkField = reader.GetAttribute("xlinkfield").ToString();
                    aLayer.HLinkField = reader.GetAttribute("hlink").ToString();
                    aLayer.HLinkParams = reader.GetAttribute("hparams").ToString();
                    if (aLayer.Active)
                    {
                        hasActiveLayer = true;
                        stxtActiveLayer.Text = iLyrCount.ToString();
                        stxtActiveLayerName.Text = aLayer.Name;
                        txbLayerInfo.Text = Gaiocorp.SLMapViewer.Resources.SLMapViewer.ActiveLayer.ToString() + " " + aLayer.Title;
                    }
                    aLayer.IdField = reader.GetAttribute("idfield").ToString();
                    aLayer.IdField = reader.GetAttribute("idname").ToString();
                    iLyrCount++;
                }

                if (reader.NodeType == XmlNodeType.Element && reader.Name == "FIELD")
                {
                    aLayer.Fields.Add(new LayerField(reader.GetAttribute("name").ToString()));
                }

                if (reader.NodeType == XmlNodeType.Element && reader.Name == "CLASS")
                {
                    aLayer.Symbols.Add(new LegendSymbol(reader.GetAttribute("name").ToString(), reader.GetAttribute("symbolURL").ToString()));
                }


                if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "LAYER")
                {
                    allLyrs.Add(aLayer);
                }

                if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "LEGEND")
                {
                    break;
                }

            }

            reader.Close();
            if (!hasActiveLayer)
            {
                SelectImg_rect.Visibility = Visibility.Collapsed;
                SelectImg.Visibility = Visibility.Collapsed;
                InfoImg_rect.Visibility = Visibility.Collapsed;
                InfoImg.Visibility = Visibility.Collapsed;
                HyperlImg_rect.Visibility = Visibility.Collapsed;
                HyperlImg.Visibility = Visibility.Collapsed;
            }
            else
            {
                SelectImg_rect.Visibility = Visibility.Visible;
                SelectImg.Visibility = Visibility.Visible;
                InfoImg_rect.Visibility = Visibility.Visible;
                InfoImg.Visibility = Visibility.Visible;

                LegendLayer activeLayer = allLyrs.getActiveLayer();
                if (activeLayer != null)
                {
                    if (activeLayer.HLinkField != "NONE")
                    {
                        HyperlImg_rect.Visibility = Visibility.Visible;
                        HyperlImg.Visibility = Visibility.Visible;
                    }
                    else
                    {
                        HyperlImg_rect.Visibility = Visibility.Collapsed;
                        HyperlImg.Visibility = Visibility.Collapsed;
                    }
                }
            }
            //DrawLegend();
            DrawLegendTree();
        }

        private void DrawLegendTree()
        {
            foreach (LegendLayer obj in allLyrs)
            {
                if (gridLegend.Tag == null)
                {
                    Node LayerNode = new Node(obj.Name, obj.Title, true);
                    LayerNode.IsChecked = obj.Visible;
                    LayerNode.Popup = obj.Title;

                    if (obj.EnableActive == true || obj.IsAnnotation != true)
                        LayerNode.Tag = obj.Index;
                    else
                        LayerNode.Tag = null;
                    //LayerNode.a
                    //LayerNode.SelectedForeground = new SolidColorBrush(Colors.Red);
                    if (obj.Active)
                    {
                        LayerNode.Foreground = new SolidColorBrush(Colors.Red);
                        LayerNode.Popup = LayerNode.Title + " (" + Gaiocorp.SLMapViewer.Resources.SLMapViewer.ActiveLayer.ToString() + ")";
                    }
                    AddNodes(treeLegend, LayerNode);
                    LayerNode.NodeCheckChanged += new TreeEventHandler(LayerNode_NodeCheckChanged);
                    foreach (LegendSymbol objSym in obj.Symbols)
                    {
                        Image tempImg = new Image();
                        if (obj.IsAnnotation != true)
                        {

                            Node SymbolNode = new Node(objSym.Name, objSym.Name, false, objSym.SymbolUri);
                            SymbolNode.Popup = objSym.Name;
                            SymbolNode.IsEnabled = false;
                            SymbolNode.IsEditable = false;
                            SymbolNode.IsChecked = true;
                            AddNodes(LayerNode, SymbolNode);
                        }
                    }
                }
                //else
                //{
                //    if (obj.Active == true)
                //    {
                //        SetActiveLayer(this.gridLegend, obj.Name);
                //    }
                //}
            }
            //Set the Tag of the Grid Legend to the Layers class
            if (allLyrs.Count > 0)
            {
                int ir = gridLegend.RowDefinitions.Count;
                gridLegend.Tag = allLyrs;
                treeLegend.ExpandAll();
            }
        }

        private void AddNodes(Node parentNode, Node childNode)
        {
            parentNode.BulkUpdateBegin();
            parentNode.Nodes.Add(childNode);
            parentNode.BulkUpdateEnd();
        }

        private void LayerNode_NodeCheckChanged(object sender, TreeEventArgs e)
        {
            Node aNode = (Node)sender;
            xmlString = "<REQUEST action='SetLegend' sessionid='" + _parameters["SessionID"] + "'>";
            xmlString = xmlString + "<LAYER name='" + aNode.ID + "' visible='" + Convert.ToString(Convert.ToInt32(aNode.IsChecked)) + "' />";
            xmlString = xmlString + "</REQUEST>";
            stxtRequest.Text = xmlString;
            //xbtnApplyLegend_Click(null, null);
        }
        private void treeLegend_NodeClick(object sender, TreeEventArgs e)
        {
            Node aNode = e.Target;
            if (aNode.Tag != null)
            {
                xmlString = "<REQUEST action='SetLegend' sessionid='" + _parameters["SessionID"] + "'>";
                xmlString = xmlString + "<ACTIVE_INDEX>" + aNode.Tag.ToString() + "</ACTIVE_INDEX>";
                xmlString = xmlString + "</REQUEST>";
                stxtRequest.Text = xmlString;
                ShowActiveLayerinTree(aNode);
            }
        }

        private void ShowActiveLayerinTree(Node activeNode)
        {
            foreach (Node aNode in treeLegend.Nodes)
            {
                if (aNode.ID == activeNode.ID)
                {
                    aNode.Foreground = new SolidColorBrush(Colors.Red);
                    aNode.SelectedForeground = new SolidColorBrush(Colors.Red);
                    aNode.Popup = aNode.Title + " (" + Gaiocorp.SLMapViewer.Resources.SLMapViewer.ActiveLayer.ToString() + ")";
                }
                else
                    aNode.Foreground = new SolidColorBrush(Colors.Black);
            }

        }
        private void DrawLegend()
        {
            Int32 ih = 0;
            int symbolPosition = 0;
            int lyrCount = 0;
            RowDefinition newRow = new RowDefinition();
            int iObjCounter = 0;

            foreach (LegendLayer obj in allLyrs)
            {
                if (gridLegend.Tag == null)
                {
                    newRow = new RowDefinition();
                    symbolPosition = 0;
                    lyrCount = lyrCount + 1;
                    TextBlock aTb = createTextBox(obj.Title, obj.Index, lyrCount);
                    aTb.Tag = obj.Name;
                    gridLegend.RowDefinitions.Add(newRow);
                    newRow.Height = new GridLength(ih);
                    gridLegend.Children.Add(aTb);
                    CheckBox aCb = createCheckBox(obj.Visible, lyrCount);
                    aCb.Tag = obj.Name;
                    gridLegend.Children.Add(aCb);
                    if (obj.EnableActive == true || obj.IsAnnotation != true)
                    {
                        RadioButton aRb = createRadioButton(obj.Active, lyrCount);
                        aRb.Tag = obj.Index;
                        gridLegend.Children.Add(aRb);
                    }
                    foreach (LegendSymbol objSym in obj.Symbols)
                    {
                        Canvas aCnv = new Canvas();
                        Image tempImg = new Image();
                        if (obj.IsAnnotation != true)
                        {
                            tempImg.Source = objSym.SymbolImage;
                        }
                        else
                        {
                            //tempImg.Source = objSym.SymbolImage;
                        }
                        tempImg.Width = 40;
                        tempImg.Height = 15;
                        tempImg.SetValue(Canvas.TopProperty, Convert.ToDouble(symbolPosition));
                        aCnv.Children.Add(tempImg);
                        TextBlock aTb1 = new TextBlock();
                        aTb1.Text = objSym.Name;
                        aTb.TextWrapping = TextWrapping.Wrap;
                        aTb1.SetValue(Canvas.TopProperty, Convert.ToDouble(symbolPosition));
                        aTb1.SetValue(Canvas.LeftProperty, Convert.ToDouble(40));
                        aTb1.TextWrapping = TextWrapping.Wrap;
                        aCnv.Children.Add(aTb1);
                        aCnv.SetValue(Grid.RowProperty, 3 + lyrCount);
                        aCnv.SetValue(Grid.ColumnProperty, 3);
                        aCnv.Width = 150;
                        gridLegend.Children.Add(aCnv);
                        symbolPosition = symbolPosition + 20;
                        gridLegCont.UpdateLayout();
                        ih = ih + 15;
                    }
                    double h = 0;
                    // If the layer has only one symbol
                    // set the row height to 20pixels
                    if (obj.Symbols.Count == 1)
                        h = 20;
                    // else multiply 20 by the number of symbols
                    else
                        h = (obj.Symbols.Count * 20);

                    RowDefinition curRow = gridLegend.RowDefinitions[3 + lyrCount];
                    curRow.Height = new GridLength(h);
                    symbolPosition = 0;
                    ih = 0;

                }
                else
                {
                    SetLegendLayerVisibility(this.gridLegend, obj.Name, obj.Visible);
                    if (obj.Active == true)
                    {
                        SetActiveLayer(this.gridLegend, obj.Name);
                    }
                    iObjCounter++;

                }

            }
            //Set the Tag of the Grid Legend to the Layers class
            if (allLyrs.Count > 0)
            {
                int ir = gridLegend.RowDefinitions.Count;
                gridLegend.Tag = allLyrs;
            }

        }
        private CheckBox createCheckBox(bool isChecked, int lyrCount)
        {
            CheckBox aCb = new CheckBox();
            aCb.IsChecked = isChecked;
            aCb.SetValue(Grid.RowProperty, 3 + lyrCount);
            aCb.SetValue(Grid.ColumnProperty, 1);
            aCb.HorizontalAlignment = HorizontalAlignment.Center;
            return aCb;
        }

        private RadioButton createRadioButton(bool isSelected, int lyrCount)
        {
            RadioButton aRb = new RadioButton();
            aRb.IsChecked = isSelected;
            aRb.SetValue(Grid.RowProperty, 3 + lyrCount);
            aRb.SetValue(Grid.ColumnProperty, 2);
            aRb.HorizontalAlignment = HorizontalAlignment.Center;
            return aRb;
        }
        private TextBlock createTextBox(string title, int index, int lyrCount)
        {
            TextBlock aTb = new TextBlock();
            aTb.Text = title;
            aTb.Tag = index;
            aTb.SetValue(Grid.RowProperty, 3 + lyrCount);
            aTb.SetValue(Grid.ColumnProperty, 0);
            return aTb;
        }

        private void xbtnApplyLegend_Click(object sender, RoutedEventArgs e)
        {
            xmlString = "<REQUEST action='SetLegend'>";
            //SetLayerVisibility(this.gridLegend);
            //FindActiveLayer(this.gridLegend);
            xmlString = xmlString + "</REQUEST>";
            stxtRequest.Text = xmlString;
        }
        void SetLayerVisibility(DependencyObject parent)
        {
            int numChildren = VisualTreeHelper.GetChildrenCount(parent);

            for (int i = 0; i < numChildren; i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, i);

                if (child.GetType() == typeof(CheckBox))
                {
                    CheckBox aCb = (CheckBox)child;
                    xmlString = xmlString + "<LAYER name='" + aCb.Tag.ToString() + "' visible='" + Convert.ToString(Convert.ToInt32(aCb.IsChecked)) + "' />";
                }
                SetLayerVisibility(child);
            }
        }
        void FindActiveLayer(DependencyObject parent)
        {
            int numChildren = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < numChildren; i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, i);

                if (child.GetType() == typeof(RadioButton))
                {
                    RadioButton aRb = (RadioButton)child;
                    if (aRb.IsChecked == true)
                    {
                        xmlString = xmlString + "<ACTIVE_INDEX>" + aRb.Tag.ToString() + "</ACTIVE_INDEX>";
                        break;
                    }
                }
                FindActiveLayer(child);
            }
            //  if (!isChecked) xmlString = xmlString + "<ACTIVE_INDEX>-1</ACTIVE_INDEX>";

        }
        void SetLegendLayerVisibility(DependencyObject parent, string sLyrName, bool isChecked)
        {
            int numChildren = VisualTreeHelper.GetChildrenCount(parent);

            for (int i = 0; i < numChildren; i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, i);

                if (child.GetType() == typeof(CheckBox))
                {
                    CheckBox aCb = (CheckBox)child;
                    if (aCb.Tag.ToString() == sLyrName)
                    {
                        aCb.IsChecked = isChecked;
                    }
                }
                SetLegendLayerVisibility(child, sLyrName, isChecked);
            }
        }
        void SetActiveLayer(DependencyObject parent, string sLyrName)
        {
            int numChildren = VisualTreeHelper.GetChildrenCount(parent);
            bool foundLayer = false;
            for (int i = 0; i < numChildren; i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, i);

                if (child.GetType() == typeof(TextBlock))
                {
                    TextBlock aTb = (TextBlock)child;
                    if (aTb.Tag != null)
                    {
                        if (aTb.Tag.ToString() == sLyrName)
                            foundLayer = true;
                    }
                }
                if (child.GetType() == typeof(RadioButton))
                {
                    RadioButton aRb = (RadioButton)child;
                    if (foundLayer == true)
                    {
                        aRb.IsChecked = true;
                        break;
                    }
                }
                SetActiveLayer(child, sLyrName);
            }
            //  if (!isChecked) xmlString = xmlString + "<ACTIVE_INDEX>-1</ACTIVE_INDEX>";

        }

        private void xbtnCloseLegend_Click(object sender, RoutedEventArgs e)
        {
            this.cnvLegend.Visibility = Visibility.Collapsed;
        }
        #endregion

        #region Identify Grid

        private void CreateIdentifyGrid(string xmlResponse)
        {
            bool hasSelection = false;
            bool isNewRec = false;
            bool blDisplayXLinkButton = false;
            string sXLinkField = string.Empty;
            if (xmlResponse == string.Empty)
            {
                return;
            }

            LegendLayers allLyr = (LegendLayers)gridLegend.Tag;
            LegendLayer aLyr = allLyr.getLayerByName(stxtActiveLayerName.Text);
            if (aLyr != null)
            {
                sXLinkField = aLyr.XLinkField;
            }

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.XmlResolver = new XmlXapResolver();

            XmlReader reader = XmlReader.Create(new StringReader(xmlResponse));

            reader.MoveToContent();
            while (reader.Read())
            {

                if (reader.NodeType == XmlNodeType.Element && reader.Name == "RESULTSET")
                {
                    hasSelection = true;
                    // Clear the data grid columns
                    gridDataResults.Columns.Clear();
                    bool blAddRb = Convert.ToBoolean(Convert.ToInt32(reader.GetAttribute("showLinkButton")));
                    string scount = reader.GetAttribute("count");
                    string sLayer = reader.GetAttribute("layertitle");
                    ResultsTitle.Text = Gaiocorp.SLMapViewer.Resources.SLMapViewer.SearchResultsTitle + " (" + sLayer + ")";
                    ResultsTitle.Tag = reader.GetAttribute("layername");

                    //System.Resources.ResourceManager RM = new ResourceManager("SLMapViewer", System.Reflection.Assembly.GetExecutingAssembly());
                    ResultsCount.Text = Gaiocorp.SLMapViewer.Resources.SLMapViewer.NoOfSelRecs.ToString() + ": " + scount;
                }

                if (reader.NodeType == XmlNodeType.Element && reader.Name == "SELECTEDFIELD")
                {
                    string strFieldName = reader.GetAttribute("name");
                    if (strFieldName.ToUpper().Trim() == sXLinkField.ToUpper().Trim())
                    {
                        blDisplayXLinkButton = true;
                        imgShowExtDetails.Tag = sXLinkField.ToUpper().Trim();
                    }
                    //Console.WriteLine(strFieldName);
                    this.gridDataResults.Columns.Add(
                            new DataGridTextColumn
                            {
                                Header = strFieldName,
                                Binding = new Binding(strFieldName)
                            });

                }

                if (reader.NodeType == XmlNodeType.Element && reader.Name == "TABLE")
                {
                    isNewRec = true;
                    // Clear the data grid columns
                    gridDataResults.Columns.Clear();
                    bool blAddRb = Convert.ToBoolean(Convert.ToInt32(reader.GetAttribute("showLinkButton")));
                    //string scount = reader.GetAttribute("count");
                    //string sLayer = reader.GetAttribute("layertitle");
                    //ResultsTitle.Text = Gaiocorp.SLMapControl.Resources.SLMapViewer.SearchResultsTitle + " (" + sLayer + ")";
                    //ResultsTitle.Tag = reader.GetAttribute("layername");

                    ////System.Resources.ResourceManager RM = new ResourceManager("SLMapViewer", System.Reflection.Assembly.GetExecutingAssembly());
                    //ResultsCount.Text = Gaiocorp.SLMapControl.Resources.SLMapViewer.NoOfSelRecs.ToString() + scount;
                }

                if (reader.NodeType == XmlNodeType.Element && reader.Name == "TABFIELD")
                {
                    string strFieldName = reader.GetAttribute("name");
                    if (strFieldName.ToUpper().Trim() == sXLinkField.ToUpper().Trim())
                    {
                        blDisplayXLinkButton = true;
                        imgShowExtDetails.Tag = sXLinkField.ToUpper().Trim();
                    }
                    //Console.WriteLine(strFieldName);
                    this.gridDataResults.Columns.Add(
                            new DataGridTextColumn
                            {
                                Header = strFieldName,
                                Binding = new Binding(strFieldName)
                            });

                }
                if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "RESULT")
                {
                    break;
                }

            }
            reader.Close();

            try
            {
                if (hasSelection == true)
                    this.gridDataResults.ItemsSource = GenerateData(xmlResponse).ToDataSource();

                if (isNewRec == true)
                    this.gridDataResults.ItemsSource = GenerateNewData(xmlResponse).ToDataSource();

            }
            catch (Exception ex) { }
            if (blDisplayXLinkButton) imgShowExtDetails.Visibility = Visibility.Visible;
            else imgShowExtDetails.Visibility = Visibility.Collapsed;
        }

        public IEnumerable<IDictionary> GenerateData(string xmlResponse)
        {
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.XmlResolver = new XmlXapResolver();

            XmlReader reader = XmlReader.Create(new StringReader(xmlResponse));

            reader.MoveToContent();
            var dict = new Dictionary<string, object>();
            int iCount = 0;
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element && reader.Name == "SELECTEDFIELD")
                {
                    iCount = iCount + 1;
                    string strFieldName = reader.GetAttribute("name");
                    string strFieldValue = reader.GetAttribute("value");
                    dict[strFieldName] = strFieldValue;
                }
                if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "RESULT")
                {
                    yield return dict;
                }

                if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "RESULTSET")
                {
                    break;
                }
            }
            reader.Close();
            //this.gridDataResults.ItemsSource = dict;

        }

        public IEnumerable<IDictionary> GenerateNewData(string xmlResponse)
        {
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.XmlResolver = new XmlXapResolver();

            XmlReader reader = XmlReader.Create(new StringReader(xmlResponse));

            reader.MoveToContent();
            var dict = new Dictionary<string, object>();
            int iCount = 0;
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element && reader.Name == "TABFIELD")
                {
                    iCount = iCount + 1;
                    string strFieldName = reader.GetAttribute("name");
                    string strFieldValue = reader.GetAttribute("value");
                    dict[strFieldName] = strFieldValue;
                }
                if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "TABLE")
                {
                    yield return dict;
                }


            }
            reader.Close();
            //this.gridDataResults.ItemsSource = dict;

        }

        private void gridDataResults_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (gridDataResults.SelectedIndex == -1)
            {
                imgShowExtDetails.Visibility = Visibility.Collapsed;
                imgZoomToResult.Visibility = Visibility.Collapsed;
            }
            else
            {
                //imgShowExtDetails.Visibility = Visibility.Visible;
                imgZoomToResult.Visibility = Visibility.Visible;
            }
        }

        private void imgCloseResult_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.brdResults.Visibility = Visibility.Collapsed;
        }
        private void xbtnCloseResults_Click(object sender, RoutedEventArgs e)
        {
            this.brdResults.Visibility = Visibility.Collapsed;
        }
        private void imgZoomToResult_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            object selItems = gridDataResults.SelectedItem;
            if (this.gridDataResults.SelectedItem != null)
            {
                var t = this.gridDataResults.SelectedItem.GetType();
                var sFID = (string)t.GetProperty("FID").GetValue(this.gridDataResults.SelectedItem, null);
                stxtRequest.Text = "<REQUEST action='IDQuery' shpid='" + sFID.ToString() + "' layer='" + ResultsTitle.Tag.ToString() + "' sessionid='" + _parameters["SessionID"] + "' />";
            }
        }

        private void imgShowExtDetails_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            HtmlElement extText = HtmlPage.Document.GetElementById(_parameters["TargetControlID"].ToString());
            var t = this.gridDataResults.SelectedItem.GetType();
            string sFieldName = imgShowExtDetails.Tag.ToString();
            var sVal = (string)t.GetProperty(sFieldName).GetValue(this.gridDataResults.SelectedItem, null);
            //extText.
            //extText.SetProperty("value", sVal);
            //HtmlElement extText1 = HtmlPage.Document.GetElementById("txtSLResponse");
            extText.Focus();
            extText.SetProperty("value", sVal);
            HtmlElement txtRequest = HtmlPage.Document.GetElementById(_parameters["RequestControlID"].ToString());
            txtRequest.Focus();

        }

        # endregion

        # region Query Grid

        private void BindCboToLayers()
        {
            if (gridQuery.Tag == null)
            {
                if (gridLegend.Tag != null)
                {
                    LegendLayers allLyr = (LegendLayers)gridLegend.Tag;
                    cboLayers.Items.Clear();
                    foreach (LegendLayer aLyr in allLyr)
                    {
                        cboLayers.Items.Add(aLyr.Title);
                    }
                    if (allLyr.Count > 0)
                        cboLayers.SelectedIndex = 0;
                }
            }
        }

        private void cboLayers_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int s = cboLayers.SelectedIndex;
            if (s != -1)
            {
                LegendLayers allLyr = (LegendLayers)gridLegend.Tag;
                LegendLayer aLyr = allLyr.getLayerByTitle(cboLayers.SelectedItem.ToString());
                lsAttrs.Items.Clear();
                foreach (LayerField aField in aLyr.Fields)
                {
                    lsAttrs.Items.Add(aField.Name);
                }
                txbQSelect.Text = "SELECT * FROM " + aLyr.Title + " WHERE :";
                gridQuery.Tag = aLyr;
            }
        }

        private void lsAttrs_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lsAttrs.SelectedIndex >= 0)
            {
                txtQuery.Text = txtQuery.Text + " " + lsAttrs.SelectedItem.ToString();
            }


        }
        private void lsAttrs_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            lsAttrs.SelectedIndex = -1;
        }

        private void cboOps_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ItemCollection ic = cboOps.Items;
            if (cboOps.SelectedIndex >= 0)
            {
                if (txtQuery.Text.Trim() != string.Empty)
                {
                    ComboBoxItem cbi = (ComboBoxItem)cboOps.SelectedItem;
                    txtQuery.Text = txtQuery.Text + " " + cbi.Content.ToString() + " ";
                }
            }
        }

        private void btnCloseQuery_Click(object sender, RoutedEventArgs e)
        {
            brdQuery.Visibility = Visibility.Collapsed;
        }

        private void btnDoQuery_Click(object sender, RoutedEventArgs e)
        {
            string sWhere = txtQuery.Text.Replace(@"'", @"""");
            sWhere = sWhere.Trim();
            LegendLayer aLyr = (LegendLayer)gridQuery.Tag;
            string sLayerName = aLyr.Name;
            stxtRequest.Text = "<REQUEST action='AttributeQuery' layer='" + sLayerName + "' where='" + sWhere + "' sessionid='" + _parameters["SessionID"] + "' />";
        }


        # endregion

        #region Navigate To Url
        private void GoToUrl(string sUrl)
        {
            HtmlPage.Window.Navigate(new Uri(sUrl), "_blank");
        }


        #endregion




        #region Measure Tool


        #endregion

        #region Print Tool

        private void btnPrint_Click(object sender, RoutedEventArgs e)
        {
            ComboBoxItem cbi = (ComboBoxItem)cboPaperSizes.SelectedItem;
            if (stxtRequest.Text == "<REQUEST action='Print' pscale='" + txtPrintScale.Text + "' psize='" + cbi.Tag.ToString() + "' sessionid=" + _parameters["SessionID"] + "' />")
            {
                stxtRequest_TextChanged(stxtRequest, null);
            }
            else
                stxtRequest.Text = "<REQUEST action='Print' pscale='" + txtPrintScale.Text + "' psize='" + cbi.Tag.ToString() + "' sessionid='" + _parameters["SessionID"] + "' />";
        }

        private void btnPrintClose_Click(object sender, RoutedEventArgs e)
        {
            brdPrint.Visibility = Visibility.Collapsed;
        }
        #endregion

        #region Error
        private void btnErrorClose_Click(object sender, RoutedEventArgs e)
        {
            brdError.Visibility = Visibility.Collapsed;
        }
        #endregion

    }
}
